﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; using Montana.DAC;
using System.Data;

namespace Montana.Entidades
{
    public class Recibo : Datos<Recibo>
    {
        public DateTime Fecha { get; set; }
        public int IDCliente { get; set; }
        public string Cliente { get; set; }
        public decimal Importeefectivo { get; set; }
        public decimal Importecheques { get; set; }
        public decimal Importeresagos { get; set; }
        public decimal Saldoanterior { get; set; }
        public decimal Saldonuevo { get; set; }

        decimal total;
        public decimal Total 
        { 
            get
            {
                return Importeefectivo + Importecheques + Importeresagos;
            }
            set 
            {
                total = value;
            } 
        }

        public decimal TotalEntregado
        {
            get
            {
                return Importeefectivo + Importecheques + Importeresagos;
            }
        }


        public string NumeroRecibo
        {
            get
            {
                return "0001-" + ID.ToString("00000000");
            }
        }

        protected override string SQLBasico
        {
            get
            {
                return @"select r.*, c.nombre as cliente 
                            from (recibo r inner join cliente c on r.idcliente=c.id)";
            }
        }

        public int NuevoReciboFactura(List<Cheque> cheques, List<Resago> resagos, Factura factura, NotaDebito notaDebito)
        {
            Conectar();
            IniciarTransaccion();

            string sql = "";

            try
            {
                sql = @"insert into recibo (fecha, idcliente, importeefectivo, importecheques, 
                            importeresagos, total) values 
                        (@fecha, @idcliente, @importeefectivo, @importecheques, @importeresagos, @total)";

                Ejecutar(sql, this);

                int idRecibo = (int)TraerValor("SELECT @@IDENTITY");

                foreach (Cheque che in cheques)
                {
                    sql = @"insert into recibocheque (nombre, banco, fechadeposito, idrecibo, idcliente, importe, esContable)
                            values (@nombre, @banco, @fechadeposito, @idrecibo, @idcliente, @importe, @esContable)";

                    Ejecutar(sql, che.Nombre, che.Banco, che.Fechadeposito, idRecibo, che.IDCliente, che.Importe, che.Escontable);
                }

                foreach (Resago res in resagos)
                {
                    sql = @"insert into reciboresago (nombre, kilos, preciokilo, idrecibo, esContable)
                            values (@nombre, @kilos, @preciokilo, @idrecibo, @esContable)";

                    Ejecutar(sql, res.Nombre, res.Kilos, res.Preciokilo, idRecibo, res.Escontable);
                }

                sql = @"insert into recibodocumento (idrecibo, iddocumento, importecancelado)
                        values (@idrecibo, @iddocumento, @importecancelado)";
                Ejecutar(sql, idRecibo, factura.ID, this.Total);


                TerminarTransaccion();

                return idRecibo;
            }
            catch (Exception ex)
            {
                AbortarTransaccion();
                throw ex;
            }
        }

        public int NuevoRecibo(List<Cheque> cheques, List<Resago> resagos, List<IDocumento> documentos)
        {
            Conectar();
            IniciarTransaccion();

            string sql = "";

            try
            {
                sql = @"insert into recibo (fecha, idcliente, importeefectivo, importecheques, 
                            importeresagos, total, saldoanterior, saldonuevo) values 
                        (@fecha, @idcliente, @importeefectivo, @importecheques, @importeresagos, 
                            @total, @saldoanterior, @saldonuevo)";
                Ejecutar(sql, this);

                int idRecibo = (int)TraerValor("SELECT @@IDENTITY");

                foreach (Cheque che in cheques)
                {
                    sql = @"insert into recibocheque (nombre, banco, fechadeposito, idrecibo, idcliente, importe, esContable)
                            values (@nombre, @banco, @fechadeposito, @idrecibo, @idcliente, @importe, @esContable)";

                    Ejecutar(sql, che.Nombre, che.Banco, che.Fechadeposito, idRecibo, che.IDCliente, che.Importe, che.Escontable);
                }

                foreach (Resago res in resagos)
                {
                    sql = @"insert into reciboresago (nombre, kilos, preciokilo, idrecibo, esContable)
                            values (@nombre, @kilos, @preciokilo, @idrecibo, @esContable)";

                    Ejecutar(sql, res.Nombre, res.Kilos, res.Preciokilo, idRecibo, res.Escontable);
                }

                decimal totalCancelado = 0;
                foreach (IDocumento doc in documentos)
                {
                    //guarda el detalle de los documentos cancelados en el recibo
                    sql = @"insert into recibodocumento (idrecibo, iddocumento, importecancelado)
                        values (@idrecibo, @iddocumento, @importecancelado)";
                    Ejecutar(sql, idRecibo, doc.ID, doc.Importecancelado);

                    totalCancelado += doc.Importecancelado;

                    //actualiza el sado de cada documento cancelado
                    if (doc.Tipo == "FC")
                    {
                        sql = @"update factura set importecancelado = importecancelado + @importecancelado where id=@id";
                        Ejecutar(sql, doc.Importecancelado, doc.ID);
                    }
                }

                if (TotalEntregado > totalCancelado)
                {
                    decimal nuevoSaldo = (TotalEntregado - totalCancelado) * -1;

                    sql = "update cliente set saldo=saldo + @nuevoSaldo where id=@id";
                    Ejecutar(sql, nuevoSaldo, this.IDCliente);
                }

                TerminarTransaccion();

                return idRecibo;
            }
            catch (Exception ex)
            {
                AbortarTransaccion();
                throw ex;
            }
        }

        public void ReporteRecibo(DataSet ds, int idRecibo)
        {
            DataTable dt = TraerDataSet(SQLBasico + " where r.id=" + idRecibo).Tables[0];
            dt.TableName = "Recibo";
            ds.Tables.Add(dt.Clone());

            dt = TraerDataSet("select * from recibocheque where idrecibo=" + idRecibo).Tables[0];
            dt.TableName = "ReciboCheque";
            ds.Tables.Add(dt.Clone());

            dt = TraerDataSet("select * from recibodocumento where idrecibo=" + idRecibo).Tables[0];
            dt.TableName = "ReciboDocumento";
            ds.Tables.Add(dt.Clone());

            dt = TraerDataSet("select * from reciboresago where idrecibo=" + idRecibo).Tables[0];
            dt.TableName = "ReciboResago";
            ds.Tables.Add(dt.Clone());
        }

        public List<Recibo> BuscarPorCliente(string cliente)
        {
            return TraerObjetos(SQLBasico + " where c.nombre like '%" + cliente + "%'");
        }
    }
}
